﻿
#ifndef ModelBone_h
#define ModelBone_h

#include <System/Collections/Generic/RList.h>

#include <Riccsson/Xna/Framework/RMatrix.h>
#include <Riccsson/Xna/Framework/ModelMesh.h>

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
				// Summary:
				//     Represents bone data for a model. Reference page contains links to related
				//     conceptual articles.
				class ModelBone sealed
				{

					PROP3(ModelBone, GC_PTR<Riccsson::System::Collections::Generic::List<GC_PTR<ModelMesh>>>, Meshes)
					PROP3(ModelBone, GC_PTR<ModelBoneCollection>, Children)
					PROP3(ModelBone, int, Index)
					PROP3(ModelBone, GC_PTR<Riccsson::System::string>, Name)
					PROP3(ModelBone, GC_PTR<ModelBone>, Parent)
					PROP3(ModelBone, Matrix, Parent)
					PROP3(ModelBone, Matrix, ModelTransform)

					private: GC_PTR<Riccsson::System::Collections::Generic::List<GC_PTR<ModelBone>>> children;
					private: GC_PTR<Riccsson::System::Collections::Generic::List<GC_PTR<ModelMesh>>> meshes;

					public:  PROP3_GET(GC_PTR<Riccsson::System::Collections::Generic::List<GC_PTR<ModelMesh>>>, Meshes)
					{
						return this->meshes;
					}
					private:  PROP3_SET(GC_PTR<Riccsson::System::Collections::Generic::List<GC_PTR<ModelMesh>>>, Meshes)
					{
						meshes = value;
					}

					// Summary:
					//     Gets a collection of bones that are children of this bone.
					public:  PROP3_GET(GC_PTR<ModelBoneCollection>, Children)
					{
						return this->meshes;
					}
					private:  PROP3_SET(GC_PTR<ModelBoneCollection>, Children)
					{
						meshes = value;
					}

					//
					// Summary:
					//     Gets the index of this bone in the Bones collection.
					public: PROP3_GET(int, Index)
					{
						throw;
					}
					public: PROP3_SET(int, Index)
					{
						throw;
					}

					//
					// Summary:
					//     Gets the name of this bone.
					public: PROP3_GET(GC_PTR<Riccsson::System::string>, Name)
					{
						throw;
					}
					public: PROP3_SET(GC_PTR<Riccsson::System::string>, Name)
					{
						throw;
					}

					//
					// Summary:
					//     Gets the parent of this bone.
					public: PROP3_GET(GC_PTR<ModelBone>, Parent)
					{
						throw;
					}
					public: PROP3_SET(GC_PTR<ModelBone>, Parent)
					{
						throw;
					}
							
					private: Matrix transform;
					//
					// Summary:
					//     Gets or sets the matrix used to transform this bone relative to its parent
					//     bone.
					public: PROP3_GET(Matrix, Parent)
					{
						return this->transform;
					}
					public: PROP3_SET(Matrix, Parent)
					{
						this->transform = value;
					}

		
					/// <summary>
					/// Transform of this node from the root of the model not from the parent
					/// </summary>
					public: PROP3_GET(Matrix, ModelTransform)
					{
						throw;
					}
					public: PROP3_SET(Matrix, ModelTransform)
					{
						throw;
					}
		
					public: ModelBone ()
						: PROP3_INIT(ModelBone, Meshes)
						, PROP3_INIT(ModelBone, Children)
						, PROP3_INIT(ModelBone, Index)
						, PROP3_INIT(ModelBone, Name)
						, PROP3_INIT(ModelBone, Parent)
						, PROP3_INIT(ModelBone, Parent)
						, PROP3_INIT(ModelBone, ModelTransform)
					{
						children = new Riccsson::System::Collections::Generic::List<GC_PTR<ModelBone>>();
						
						meshes = new Riccsson::System::Collections::Generic::List<GC_PTR<ModelMesh>>();
						Children = new ModelBoneCollection(new Riccsson::System::Collections::Generic::List<GC_PTR<ModelBone>>());
					}
		
					public: void AddMesh(ModelMesh* mesh)
					{
						meshes->Add(mesh);
					}

					public: void AddChild(ModelBone* modelBone)
					{
						children->Add(modelBone);
						Children = new ModelBoneCollection(children);
					}
				};
			}
		}
	}
}

#endif